package com.photovoltaic.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.photovoltaic.auth.entity.Permission;
import com.photovoltaic.auth.entity.Role;
import com.photovoltaic.auth.entity.User;
import com.photovoltaic.auth.entity.UserPermission;
import com.photovoltaic.auth.entity.UserRole;
import com.photovoltaic.auth.mapper.PermissionMapper;
import com.photovoltaic.auth.mapper.RolePermissionMapper;
import com.photovoltaic.auth.mapper.UserMapper;
import com.photovoltaic.auth.mapper.UserPermissionMapper;
import com.photovoltaic.auth.mapper.UserRoleMapper;
import com.photovoltaic.auth.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserRoleMapper userRoleMapper;
    private final PermissionMapper permissionMapper;
    private final UserPermissionMapper userPermissionMapper;
    private final RolePermissionMapper rolePermissionMapper;
    
    @Override
    public User findByUsername(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return getOne(queryWrapper);
    }
    
    @Override
    public boolean existsByUsername(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return count(queryWrapper) > 0;
    }
    
    @Override
    public boolean existsByEmail(String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email);
        return count(queryWrapper) > 0;
    }
    
    @Override
    public List<Permission> getUserPermissions(Long userId) {
        return baseMapper.getUserPermissions(userId.intValue());
    }
    
    @Override
    public List<Role> getUserRoles(Long userId) {
        return baseMapper.getUserRoles(userId.intValue());
    }
    
    @Override
    @Transactional
    public boolean assignRole(Long userId, Long roleId) {
        // 检查是否已经分配
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId, userId.intValue())
                .eq(UserRole::getRoleId, roleId.intValue());
        if (userRoleMapper.selectCount(queryWrapper) > 0) {
            return true;
        }
        
        // 分配角色
        UserRole userRole = new UserRole();
        userRole.setUserId(userId.intValue());
        userRole.setRoleId(roleId.intValue());
        return userRoleMapper.insert(userRole) > 0;
    }
    
    @Override
    @Transactional
    public boolean removeRole(Long userId, Long roleId) {
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId, userId.intValue())
                .eq(UserRole::getRoleId, roleId.intValue());
        return userRoleMapper.delete(queryWrapper) > 0;
    }
    
    @Override
    @Transactional
    public boolean updateUserPermissions(Long userId, List<String> permissionKeys) {
        try {
            // 获取当前用户所有角色
            List<Role> userRoles = getUserRoles(userId);
            log.info("用户 {} 拥有的角色: {}", userId, userRoles.stream().map(Role::getRoleName).collect(Collectors.toList()));
            
            // 获取这些角色拥有的所有权限ID
            List<Long> roleIds = userRoles.stream()
                    .map(Role::getId)
                    .collect(Collectors.toList());
            
            List<Long> rolePermissionIds = new ArrayList<>();
            if (!roleIds.isEmpty()) {
                rolePermissionIds = rolePermissionMapper.getRolesPermissions(roleIds);
            }
            log.info("角色权限ID列表: {}", rolePermissionIds);
            
            // 获取所有权限的映射关系（权限Key -> 权限ID）
            List<Permission> allPermissions = permissionMapper.selectList(null);
            Map<String, Long> permissionKeyToIdMap = allPermissions.stream()
                    .collect(Collectors.toMap(Permission::getPermissionKey, Permission::getId));
            
            // 查找出用户需要的权限ID列表
            List<Long> requestedPermissionIds = permissionKeys.stream()
                    .map(permissionKeyToIdMap::get)
                    .filter(id -> id != null)
                    .collect(Collectors.toList());
            log.info("请求的权限ID列表: {}", requestedPermissionIds);
            
            // 计算需要额外授予用户的权限（在请求中但不在角色权限中的）
            List<Long> extraPermissionIds = new ArrayList<>(requestedPermissionIds);
            extraPermissionIds.removeAll(rolePermissionIds);
            log.info("需要额外授予的权限ID列表: {}", extraPermissionIds);
            
            // 设置用户直接拥有的权限
            // 1. 删除用户现有的直接权限
            userPermissionMapper.deleteByUserId(userId);
            
            // 2. 插入用户新的直接权限
            for (Long permissionId : extraPermissionIds) {
                UserPermission userPerm = new UserPermission();
                userPerm.setUserId(userId);
                userPerm.setPermissionId(permissionId);
                userPermissionMapper.insert(userPerm);
            }
            
            log.info("用户 {} 权限更新成功，直接权限数量: {}", userId, extraPermissionIds.size());
            return true;
        } catch (Exception e) {
            log.error("更新用户权限失败", e);
            return false;
        }
    }
} 